using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Comteck.Dto.Sys;
using Comteck.Extensions;
using Comteck.Ktt.Services.Sys;
using Comteck.Linq;
using Comteck.Localization;
using Comteck.Winforms;
using Comteck.Winforms.Data;
using Comteck.Winforms.Forms;
using Comteck.Winforms.Infrastructure;
using DevExpress.XtraBars;
using ExpressMapper.Extensions;
using FastReport.Design;
using WinformApp = System.Windows.Forms.Application;

namespace Comteck.Ktt.WinUI.Sys {
  /// <summary>
  /// 打印模板编辑
  /// </summary>
  public partial class FrmPrintTemplateAction : FrmEditBase {

    #region fields

    private readonly IPrintTemplateService printTemplateService;
    private PrintTemplateDto entityModel = new PrintTemplateDto();

    /// <summary>
    /// 关联脚本列表
    /// </summary>
    private CKObservableCollection<PrintTemplateDataDto> dataList;

    /// <summary>
    /// 报表控件
    /// </summary>
    private FastReport.Report report = new FastReport.Report();

    /// <summary>
    /// 报表是否已修改
    /// </summary>
    private bool IsReportModified = false;

    /// <summary>
    /// 标明是否为拷贝过来的数据
    /// </summary>
    public bool IsCopy { get; set; } = false;

    #endregion

    #region ctor

    public FrmPrintTemplateAction(IPrintTemplateService printTemplateService) {
      this.printTemplateService = printTemplateService;
      InitializeComponent();
    }

    #endregion

    #region methods




    #endregion

    #region form load

    /// <summary>
    /// 加载窗口
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void FrmPrintTemplateAction_Load(object sender, EventArgs e) {
      if (this.DesignMode) { return; }

      // 报表保存事件绑定
      environmentSettings1.DesignerSettings.CustomSaveReport += new OpenSaveReportEventHandler(cmdSave_CustomAction);

      // detail
      gcDetail.DataSource = dataList = new CKObservableCollection<PrintTemplateDataDto>(this);

      // mvvm
      mvvmContext1.BindForm(entityModel, dxValidationProvider1);
      await BindHelper.BindMenuAuth(ckMenuId);
      await this.LoadFormData();
    }

    /// <summary>
    /// 加载数据
    /// </summary>
    private async Task LoadFormData() {
      ajaxLoad.Show();
      var result = await printTemplateService.GetEditModelAsync(this.EntityId.To<string>());
      ajaxLoad.Hide();

      // 解绑模板内容修改事件
      ckData.EditValueChanged -= this.ckData_EditValueChanged;

      // 主表赋值
      result.MapTo(entityModel);

      // 关联脚本赋值
      result.DataList.MapTo(dataList, x => x.Id, x => x.Id);

      // 绑定模板内容修改事件
      ckData.EditValueChanged += this.ckData_EditValueChanged;

      // 新增
      if (string.IsNullOrWhiteSpace(entityModel.Id)) {
        btnReportDesign.Enabled = false;
        ResetReportData();
      } else {
        // 拷贝新增
        if (this.IsCopy) {
          this.Text += "-拷贝新增";
          entityModel.Id = null;
          entityModel.IsSystem = (int) EnumStatus.InValid;
          btnReportDesign.Enabled = false;

          foreach (var model in dataList) {
            model.Id = null;
          }
        } else {
          btnReportDesign.Enabled = true;
        }
      }
    }

    #endregion

    #region main data

    /// <summary>
    /// 模板内容修改事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ckData_EditValueChanged(object sender, EventArgs e) {
      IsReportModified = true;
    }

    /// <summary>
    /// 报表设计-保存事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void cmdSave_CustomAction(object sender, OpenSaveReportEventArgs e) {
      var content = report.ReportResourceString;
      ckData.EditValue = content;
      IsReportModified = true;
      this.ShowMsg("模板内容刷新成功");
    }

    /// <summary>
    /// 模板内容复位
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnResetReportData_Click(object sender, EventArgs e) {
      if (this.ShowMsg("确定对模板内容进行复位吗？", null, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) {
        return;
      }

      ResetReportData();
    }

    /// <summary>
    /// 模板内容复位
    /// </summary>
    private void ResetReportData() {
      var date = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
      var emptyStr = $@"<?xml version=""1.0"" encoding=""utf-8""?>
<Report ScriptLanguage=""CSharp"" ReportInfo.Created=""{date}"" ReportInfo.Modified=""{date}"" ReportInfo.CreatorVersion=""2013.2.5.0"">

  <Dictionary/>
  <ReportPage Name=""Page1"">
    <ReportTitleBand Name=""ReportTitle1"" Width=""718.2"" Height=""37.8""/>
    <PageHeaderBand Name=""PageHeader1"" Top=""41.8"" Width=""718.2"" Height=""28.35""/>
    <DataBand Name=""Data1"" Top=""74.15"" Width=""718.2"" Height=""75.6""/>
    <PageFooterBand Name=""PageFooter1"" Top=""153.75"" Width=""718.2"" Height=""18.9""/>
  </ReportPage>
</Report>";
      entityModel.Data = emptyStr;
    }

    /// <summary>
    /// 报表设计
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnReportDesign_Click(object sender, EventArgs e) {
      var path = WinformApp.StartupPath + @"\temp.frx";
      var encoding = new System.Text.UTF8Encoding(false);

      try {
        File.WriteAllText(path, entityModel.Data, encoding);
        report.Load(path);
      } catch (Exception ex) {
        this.ShowMsg($"打开模板内容失败,{ex.Message}");
        return;
      }

      ajaxLoad.Show();
      var result = await ServerDbDataHelper.GetPrintTemplatePrintDataSource(entityModel.Id, new List<dynamic>());
      ajaxLoad.Hide();

      if (result.Code == 1) {
        var ds = result.Data;
        report.SetParameterValue("Login_Code", SysGlobal.LoginUser.Id);
        report.SetParameterValue("Login_Name", SysGlobal.LoginUser.Name);
        report.RegisterData(ds);
        report.Design();
      } else {
        this.ShowMsg($"数据查询失败,{result.Message}");
      }
    }

    #endregion

    #region grid data

    /// <summary>
    /// 添加行
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnAddRow_Click(object sender, EventArgs e) {
      var addModel = new PrintTemplateDataDto() {
        Template_Id = entityModel.Id,
      };

      dataList.Add(addModel);
      gvDetail.RefreshData();
    }

    /// <summary>
    /// 删除行
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnDeleteRow_Click(object sender, EventArgs e) {
      if (dataList.IsNullOrEmpty()) {
        return;
      }

      if (!(gvDetail.GetFocusedRow() is PrintTemplateDataDto model)) {
        return;
      }

      dataList.Remove(model);
    }

    #endregion

    #region save

    /// <summary>
    /// 保存
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnSave_ItemClick(object sender, ItemClickEventArgs e) {
      if (await this.Save()) {
        this.DialogResult = DialogResult.OK;
      }
    }

    /// <summary>
    /// 保存
    /// </summary>
    /// <returns></returns>
    private async Task<bool> Save() {
      if (dxValidationProvider1.Validate() == false) {
        return false;
      }

      gvDetail.CloseEditor();
      gvDetail.PostEditor();

      entityModel.DataList = dataList.DataSource.ToList();

      ajaxLoad.Show();
      var result = await printTemplateService.SaveAsync(entityModel);
      ajaxLoad.Hide();

      if (result.Code == 1) {
        IsReportModified = false;
        this.ShowMsg(BaseResources.Save_Success);
        this.AddOrUpdateAction?.Invoke(result.Data);
        return true;
      } else {
        this.ShowMsg(BaseResources.Save_Failed_Reason, result.Message);
        return false;
      }
    }

    #endregion

    #region close

    /// <summary>
    /// 窗口关闭事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void FrmPrintTemplateAction_FormClosing(object sender, FormClosingEventArgs e) {
      if (IsReportModified) {
        var dialog = this.ShowMsg("当前模板内容有修改未保存,继续退出？", "提示", MessageBoxButtons.YesNo,
MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
        if (dialog == DialogResult.No) {
          e.Cancel = true;
        }
      }
    }

    /// <summary>
    /// 关闭
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnClose_ItemClick(object sender, ItemClickEventArgs e) {
      this.Close();
    }

    #endregion

  }
}
